#include "stack.h"

stack_t* stack_create(int size, int max)
{
	stack_t* stack = malloc(sizeof(stack_t));
	assert(stack);

	stack->size = size;
	stack->MAX = max;
	stack->top = 0;

	stack->data = malloc(size * max);

	return stack;
}

int stack_isfull(stack_t* stack)
{
	if(stack->top == stack->MAX)
	{
		return 1;
	}

	return 0;
}

int stack_isempty(stack_t* stack)
{
	if(stack->top == 0)
	{
		return 1;
	}

	return 0;
}

void stack_push(stack_t* stack, void* data)
{
	if(stack_isfull(stack) == 1)
	{
		printf("stack is full!\n");
		return ;
	}

	memcpy(stack->data + stack->top * stack->size, data, stack->size);

	stack->top++;
	
}

void* stack_pop(stack_t* stack)
{
	if(stack_isempty(stack) == 1)
	{
		printf("stack is empty!\n");
		return NULL;
	}

	void* data = malloc(stack->size);

	memcpy(data, stack->data + (stack->top - 1)*stack->size, stack->size);

	memset(stack->data + (stack->top - 1)*stack->size, 0, stack->size);

	stack->top--;

	return data;
}

void stack_travel(stack_t* stack, stack_op_t op)
{
	int i = 0;
	for(;i < stack->top; i++)
	{
		op((stack->data) + (i * (stack->size)));
	}
}


void stack_destroy(stack_t** stack)
{
	free((*stack)->data);
	free(*stack);
}

void stack_clean(stack_t* stack)
{
	stack->top = 0;
	memset(stack->data, 0, stack->size * stack->MAX);
}

stack_t* stack_load(char* path)
{
	FILE* fp = fopen(path, "r");
	int type_size = 0;
	int top = 0;
	int Max = 0;
	fread(&type_size, sizeof(type_size), 1, fp);
	fread(&top, sizeof(top), 1, fp);
	fread(&Max, sizeof(Max), 1, fp);

	stack_t* stack = stack_create(type_size, Max);

	stack->top = top;

	fread(stack->data, type_size, top, fp);

	fclose(fp);

	return stack;


}

void stack_store(stack_t* stack, char* path)
{
	FILE* fp = fopen(path, "w");
	fwrite(&(stack->size), sizeof(stack->size), 1, fp);
	fwrite(&(stack->top), sizeof(stack->top), 1, fp);
	fwrite(&(stack->MAX), sizeof(stack->MAX), 1, fp);
	

	fwrite(stack->data, stack->size, stack->top, fp);

	fclose(fp);

}






